#include <iostream>
#include <string>
#include <regex>

int main()
{
	// HTTP请求行格式 GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1\r\n
	std::string s = "GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.0\n";
	std::smatch re;
	
	std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)(?:\\?(.*))? (HTTP/\\d+\\.\\d+)(?:\r|\n|\r\n)?");
	// . 表示匹配除\r\n以外的所有字符
    // (GET|POST|PUT|DELETE|HEAD)：捕获组 1，匹配 HTTP 方法（五种常见方法）
	// [^?]* ：匹配非？字符，*表示0次或多次
    // (.*)：捕获组 2，匹配空格后的所有内容（包括路径、查询参数和版本号）除了\r\n
	// \\?(.*) : \\? 表示原始的字符？ (.*)表示提取？后面任意的字符0个或多个，直达遇见空格
	// (HTTP/\\d+\\.\\d+) 表示以HTTP/开头匹配任意数字 匹配.，再匹配.以后所有数字
	// (?:\r|\n|\r\n)?  (?: ... ) 表示匹配某个格式的字符串，但是不提取，最后一个？表示匹配前面的表达式0次或一次
	// (?:\\?(.*))? 
	//  (?: ... )：非捕获组（不占用捕获组编号，只用于分组）
    //  \\?：匹配字符 ?（需转义，因为 ? 在正则中是特殊元字符）
    //  (.*)：捕获组，匹配 ? 之后的任意内容（直到遇到下一个正则规则）
    //  ?：量词，表示整个非捕获组可选（匹配 0 次或 1 次）
	bool ret = std::regex_match(s,re,e);
	if(!ret)
	{
		return -1;
	}
	for (int i = 0; i < re.size(); i++) {
        std::cout << i << " : ";
        std::cout << re[i] << std::endl;
    }
	return 0;
}






// int main()
// {
// 	// HTTP请求行格式 GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1\r\n
// 	std::string s = "GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.0";
// 	std::smatch re;
	
// 	std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)\\?(.*) (HTTP/\\d+\\.\\d+)");
// 	// . 表示匹配除\r\n以外的所有字符
//     // (GET|POST|PUT|DELETE|HEAD)：捕获组 1，匹配 HTTP 方法（五种常见方法）
// 	// [^?]* ：匹配非？字符，*表示0次或多次
//     // (.*)：捕获组 2，匹配空格后的所有内容（包括路径、查询参数和版本号）除了\r\n
// 	// \\?(.*) : \\? 表示原始的字符？ (.*)表示提取？后面任意的字符0个或多个，直达遇见空格
// 	// (HTTP/\\d+\\.\\d+) 表示以HTTP/开头匹配任意数字 匹配.，再匹配.以后所有数字
// 	bool ret = std::regex_match(s,re,e);
// 	if(!ret)
// 	{
// 		return -1;
// 	}
// 	for(auto &e:re)
// 	{
// 		std::cout << e << std::endl;
// 	}
// 	return 0;
// }





// int main()
// {
// 	// HTTP请求行格式 GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1\r\n
// 	std::string s = "GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1";
// 	std::smatch re;
	
// 	std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)\\?(.*) (.*)");
//     // (GET|POST|PUT|DELETE|HEAD)：捕获组 1，匹配 HTTP 方法（五种常见方法）
// 	// [^?]* ：匹配非？字符，*表示0次或多次
//     // (.*)：捕获组 2，匹配空格后的所有内容（包括路径、查询参数和版本号）除了\r\n
// 	// \\?(.*) : \\? 表示原始的字符？ (.*)表示提取？后面任意的字符0个或多个，直达遇见空格
// 	bool ret = std::regex_match(s,re,e);
// 	if(!ret)
// 	{
// 		return -1;
// 	}
// 	for(auto &e:re)
// 	{
// 		std::cout << e << std::endl;
// 	}
// 	return 0;
// }





// int main()
// {
// 	// HTTP请求行格式 GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1\r\n
// 	std::string s = "GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1";
// 	std::smatch re;
	
// 	std::regex e("(GET|POST|PUT|DELETE|HEAD) ([^?]*)(.*)");
//     // (GET|POST|PUT|DELETE|HEAD)：捕获组 1，匹配 HTTP 方法（五种常见方法）
// 	// [^?]* ：匹配非？字符，*表示0次或多次
//     // (.*)：捕获组 2，匹配空格后的所有内容（包括路径、查询参数和版本号）除了\r\n
// 	bool ret = std::regex_match(s,re,e);
// 	if(!ret)
// 	{
// 		return -1;
// 	}
// 	for(auto &e:re)
// 	{
// 		std::cout << e << std::endl;
// 	}
// 	return 0;
// }


// int main()
// {
// 	// HTTP请求行格式 GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1\r\n
// 	std::string s = "GET /xiazelin/login?user=lixj&pass=1234 HTTP/1.1";
// 	std::smatch re;
// 	// (GET|POST|PUT|DELETE|HEAD)：捕获组 1，匹配 HTTP 方法（五种常见方法）
//     // (.*)：捕获组 2，匹配空格后的所有内容（包括路径、查询参数和版本号）除了\r\n
// 	std::regex e("(GET|POST|PUT|DELETE|HEAD) (.*)");

// 	bool ret = std::regex_match(s,re,e);
// 	if(!ret)
// 	{
// 		return -1;
// 	}
// 	for(auto &e:re)
// 	{
// 		std::cout << e << std::endl;
// 	}
// 	return 0;
// }